let w = null
//6.watcher类观察者
class Watcher{
    constructor(obj,key){
        this.obj = obj
        this.key = key
        w = this
        this.get()
        w = null
    }
    get(){
        return this.obj[this.key]
    }
    update(){
        console.log('数据修改了更新数据到视图'+this.get());
    }
}

//5.dep类依赖
class Dep{
    constructor(){
        this.subs = []
    }
    depend(watcher){
        this.subs.push(watcher)
        console.log('添加watcher到依赖类');
    }
    notify(){
        this.subs.forEach(watcher => {
            watcher.update()
        })
    }
}

//4.Observer类核心函数给每一项
function defineReactive(_data,key,value){
    observe(value)
    const dep = new Dep()
    Object.defineProperty(_data,key,{
        get(){
            if(w===null){
                dep.depend(w)
            }
            console.log('获取值');
            return value  
        },
        set(newVal){
            if(value === newVal) return
            value = newVal
            dep.notify()
            console.log('通知watcher改变');
        }
    })
}


//3.Observer类进行响应式操作
class Observer{
    constructor(_data){
        this._data = _data
        if(Array.isArray(_data)){
            this.defineArray(_data)
        }else{
            this.walk(_data)
        }
    }
    defineArray(_data){
        _data.forEach(item =>{
            observe(item)
        })
    }
    walk(_data){
        for(let key of Object.keys(_data)){
            defineReactive(_data,key,_data[key])
        }
    }
}

//2.observe函数进行数据劫持
function observe(_data){
    if(typeof _data !== 'object' || _data === null) return
    new Observer(_data)
}

//1.创建构造函数Vue,
function Vue(options){
    //放在实例上
    this._data = options.data
    //给_data数据每一项进行数据代理
    for(let key of Object.keys(this._data)){
        Object.defineProperty(this,key,{
            get(){
                return this._data[key]
            },
            set(newVal){
                this._data[key] = newVal
            }
        })
    }
    observe(this._data)
}


const vm = new Vue({
    data:{
        count:1,
        curse:{
            name:'easy',
            age:18
        }
    }
})

function huoqu(){
    new Watcher(vm,'count')
}
function shezhi(){
    vm.count = 3
}
huoqu()
shezhi()
